// import { SoaRecord } from "dns"

export function toZonefile(domain: Domain, trimDurtion: boolean = false) {
  return [
    gc2s(domain.zoneConfig, trimDurtion),
    soa2s(domain.soaRecord, trimDurtion),
    rrs2s(domain.records, trimDurtion)
  ].join('\n')
}

function gc2s(zoneConfig: ZoneConfig, trimDurtion: boolean = false) {
  const { origin, ttl } = zoneConfig
  return [`$ORIGIN ${origin}`, `$TTL ${d2s(ttl, trimDurtion)}`].join('\n')
}
function soa2s(soaRecord: SoaRecord, trimDurtion: boolean = false) {
  const { origin, ttl, clazz, type, dns, email, serial, refresh, retry, expire, minTtl } = soaRecord
  return `${origin} ${d2s(ttl, trimDurtion)} ${clazz} ${type} ${dns} ${email} (
      ${serial}
      ${d2s(refresh, trimDurtion)}
      ${d2s(retry, trimDurtion)}
      ${d2s(expire, trimDurtion)}
      ${d2s(minTtl, trimDurtion)}
      )`
}

function d2s(d: DnsDuration, trimDurtion: boolean = false) {
  if (trimDurtion) {
    d = td(d)
    // console.log(`d2s,trim:${trimDurtion},dur:${JSON.stringify(d)}`)
  }
  return `${d.value}${d.unit}`
}

function rrs2s(records: RRecord[], trimDurtion: boolean = false) {
  return records.map((d) => r2s(d, trimDurtion)).join('\n')
  // throw new Error("Function not implemented.")
}

const convertFactor: Map<string, number> = new Map([
  ['', 1],
  ['s', 1],
  ['m', 60],
  ['h', 60 * 60],
  ['d', 60 * 60 * 24],
  ['w', 60 * 60 * 24 * 7]
])

function normalizeDurtion(d: DnsDuration): DnsDuration {
  // if(!d.unit){
  //   return d;
  // }
  return {
    value: (convertFactor.get(d.unit || '') || 1) * d.value,
    unit: ''
  }
}

function td(d: DnsDuration): DnsDuration {
  const normal = normalizeDurtion(d)
  const units = ['w', 'd', 'h', 'm', 's']
  for (const unit of units) {
    const cv = convertFactor.get(unit)
    if (cv) {
      const rv = normal.value / cv
      if (Number.isInteger(rv)) {
        return {
          value: rv,
          unit
        }
      }
    }
  }
  return d
}

function r2s(value: RRecord, trimDurtion: boolean = false): string {
  const { uuid, origin, ttl, type, data, comment } = value
  // throw new Error("Function not implemented.")
  let nc
  if (comment) {
    nc = ` ; ${removelb(comment)}`
  } else {
    nc = ''
  }
  return [`; ${uuid}`, `${origin} ${d2s(ttl, trimDurtion)} IN ${type} ${data}${nc}`].join('\n')
}

function removelb(str: string): string {
  return str.replace(/[\n\r\u2028\u2029]/, ' ')
}
